﻿//Global stock variables
var gameOver = false;
var OK = false;
var time = 40;
var userCredit = 1000;
var stockList = [];
var obj1 = { fullName: "Microsoft Corporation", name: "MSFT", price: 4, raised: true, bought: 0, sold: 0 };
var obj2 = { fullName: "Apple Inc.", name: "AAPL", price: 4, raised: true, bought: 0, sold: 0 };
var obj3 = { fullName: "Bank Of America Corporation", name: "BAC", price: 4, raised: true, bought: 0, sold: 0 };
var obj4 = { fullName: "Cisco systems, Inc.", name: "CICO", price: 4, raised: true, bought: 0, sold: 0 };
var obj5 = { fullName: "eBay", name: "EBAY", price: 4, raised: true, bought: 0, sold: 0 };
var obj6 = { fullName: "Intel Corporation", name: "INTC", price: 4, raised: true, bought: 0, sold: 0 };
var obj7 = { fullName: "Targer Corporation", name: "TGT", price: 4, raised: true, bought: 0, sold: 0 };
var obj8 = { fullName: "H.J. Heinz Company", name: "HNZ", price: 4, raised: true, bought: 0, sold: 0 };
var obj9 = { fullName: "PepsiCo Inc.", name: "PEP", price: 4, raised: true, bought: 0, sold: 0 };
stockList.push(obj1);
stockList.push(obj2);
stockList.push(obj3);
stockList.push(obj4);
stockList.push(obj5);
stockList.push(obj6);
stockList.push(obj7);
stockList.push(obj8);
stockList.push(obj9);

function addUser(username, clientID){
	var result;
	var userStocks = [];
	var user = { name: username, balance: 1000, stocks: userStocks};
	result = user;
	//console.log("Adding user with name. " + username);
	return result;
}

function getUserStockByName(user, stockname){
	//console.log("Getting stocks for user: " + user.name + ".")
	for(var k = 0; k < user.stocks.length; k++){
		if(stockname == user.stocks[k].name){
			return user.stocks[k];
		}
	}	
}
function updateUserStocks(user, stockName, units){
	var userStock = getUserStockByName(user, stockName);
	var stockPrice = getStock(stockName);
	stockPrice.raised = true;
	if(userStock == null){
		//console.log("User has not bought this stock before!");
		var newStock = { name: stockName, units: units, price : stockPrice.price};
		user.balance = roundNumber( (user.balance - (stockPrice.price * units)), 2);
		//console.log("New balance is: " + user.balance);
		user.stocks.push(newStock);
	}
	else {
		userStock.units += units;
		user.balance = roundNumber( (user.balance - (stockPrice.price * units)), 2);
		//console.log("New balance is: " + user.balance);
	}
	updateOnlineUserBalance(user.clientId, user.balance);
}

function sellUserStocks(user, stockName, units){
	var userStock = getUserStockByName(user, stockName);
	var stockPrice = getStock(stockName);
	stockPrice.raised = false;
	userStock.price = stockPrice.price;
	userStock.units = userStock.units - units;
	user.balance = roundNumber( (user.balance + (stockPrice.price * units)), 2);
	updateOnlineUserBalance(user.clientId, user.balance);
	if(userStock.units <= 0){
		//console.log("Stock " + stockName + " for " + user.name + " is <= 0, removing it");
		for(var i = 0;  i < user.stocks.length; i++){
			if (user.stocks[i].name == stockName){
				user.stocks.splice(i, 1);
				break;
			}
		}
	}
}

function getStock(stockName){
	var result = null;
	for(var l = 0; l < stockList.length; l++){
		if(stockName == stockList[l].name){
			result = stockList[l];
		}
	}	
	return result;
}

function pow(number, power){
	var result = number;
	for(var i = 1; i < power; i++){
		result = result * number;
	}
	return result;
}

function updateStockPrices(stockName, units, buying){
	//console.log("Updating the stock price for: " + stockName);
	var item = getStock(stockName);
	if(item != null){
		if(buying){
			item.bought = item.bought + units;
			var newprice1 = roundNumber( (item.price * (1 + ( pow(item.bought,2) / 100 ) ) ), 2);
			if(newprice1 < 1000){
				item.price = newprice1;
			}
			else{
				item.price = 1000;
			}
			//item.price = item.price + 2;
		}
		else{
			item.sold = item.sold + units;
			var newprice2 = roundNumber( (item.price * (1 - ( pow(item.bought,2) / 100 ) ) ), 2);
			if(newprice2 > 0){
				item.price = newprice2;
			}
			else{
				item.price = 1;
			}
			//item.price = item.price - 2;
		}
	}
	else{
		console.log("Could not find stock: " + stockName);
	}
}

function updateMyStockValue(user, stockName){
	var stock = getStock(stockName)
	for(var l = 0; l < user.stocks.length; l++){
		if(user.stocks[l].name == stock.name){
			user.stocks[l].price = stock.price;
			return true;
		}
	}
	return false;
}

function removeOnlineUser(userId){
	for(var i = 0;  i < onlineUsers.length; i++){
		if (onlineUsers[i].id == userId){
			onlineUsers.splice(i, 1);
			break;
		}
	}
}

function updateOnlineUserBalance(userId, newBalance){
	for(var i = 0;  i < onlineUsers.length; i++){
		if (onlineUsers[i].id == userId){
			onlineUsers[i].balance = newBalance;
			break;
		}
	}
}

function getChatMembersofChat(roomName, newMember, userId){
	var result;
	for(var i = 0; i < chatRooms.length; i++){
		if(chatRooms[i].name == roomName){
			var mem = { name : newMember, id: userId};
			chatRooms[i].members.push(mem);
			result = chatRooms[i].members;
			break;
		}
	}
	return result;
}

function roundNumber(num, dec) {
	var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
	return result;
}

function userInChatRoom(id, roomName){
	var room = getChatRoom(roomName);
	for(var i = 0; i < room.members.length; i++){
		if(room.members[i].id == id){
			return true;
		}
	}
	return false;
}

function getChatRoom(roomName){
	var result;
	for(var i = 0; i < chatRooms.length; i++){
		if(chatRooms[i].name == roomName){
			return chatRooms[i];
		}
	}
	return result;
}
//var userRooms = getChatRoomsForUser(this.now.name, this.now.room);
function getChatRoomsForUser(id, roomName){
	var result = [];
	for(var i = 0; i < chatRooms.length; i++){
		if(userInChatRoom(id,chatRooms[i].name)){
			result.push(chatRooms[i]);
		}
	}
	return result;
}

function chatRoomNameNotInUse(roomName){
	for(var i = 0; i < chatRooms.length; i++){
		if(chatRooms[i].name == roomName){
			return false;
		}
	}	
	return true;
}

function compare(a,b) {
  if (a.balance > b.balance)
     return -1;
  if (a.balance < b.balance)
    return 1;
  return 0;
}

function createWinnerList(){
	//TODO create a winner list: onlineUsers
	return onlineUsers.sort(compare);
}

//server creation and file redering
var fs = require('fs');
//var sys = require('sys');

var static = require('../../node_modules/node-static/lib/node-static');

var file = new(static.Server)('.', { cache: 7200, headers: {'X-Hello':'World!'} });

var server = require('http').createServer(function(request, response){
	//recursive();
	request.addListener('end', function () {
		//
		// Serve files!
		//
		file.serve(request, response, function (err, res) {
			if (err) { // An error as occured
				//sys.error("> Error serving " + request.url + " - " + err.message);
				console.log("> Error serving " + request.url + " - " + err.message);
				response.writeHead(err.status, err.headers);
				response.end();
			} else { // The file was served successfully
				//sys.puts("> " + request.url + " - " + res.message);
				console.log("> " + request.url + " - " + res.message);
			}
		});
	});  
});
server.listen(8080);

var nowjs = require("now");
var everyone = nowjs.initialize(server);
var onlineUsers = [];
var chatRooms = [];

nowjs.on('connect', function(){
	OK = true;
	this.now.room = "Main Room";

	//add user information to user object
	var tempUser = addUser(this.now.name, this.user.clientId);
	this.user.name = tempUser.name;
	this.user.balance = tempUser.balance;
	this.user.stocks = tempUser.stocks;  
	//rooms = [];
	//this.user.chatRooms = rooms;
	
	nowjs.getGroup(this.now.room).addUser(this.user.clientId);
	onlineUsers.push({ name: this.now.name, id: this.user.clientId, balance: this.user.balance} );
	
	//update information on client
	this.now.initializeStockInfo(stockList, this.user, onlineUsers);
	everyone.now.updateOnlineUser(onlineUsers);
	console.log("Joined: " + this.user.name + ". balance: " + this.user.balance);
});


nowjs.on('disconnect', function(){
	removeOnlineUser(this.user.clientId);
	everyone.now.updateOnlineUser(onlineUsers);
	console.log("Left: " + this.now.name);
});

everyone.now.buyStock = function(stockName, units){
	//console.log("User wants to buy stock " + stockName + ", amount: " + units);
	var stockPrice = getStock(stockName).price;
	if( (this.user.balance - (stockPrice * parseInt(units))) > 0 ){
		//Update user object	
		updateUserStocks(this.user, stockName, parseInt(units));
		//Update stock prices
		updateStockPrices(stockName, parseInt(units), true);		
		//updateAllUserPrices(users, stockName);
		this.now.updateUserStockInfo(this.user);
		everyone.now.updateStockInfo(stockList);
		everyone.now.updateMyStockPrices(stockName);
		//everyone.now.initializeStockInfo(stockList, this.user);
		//everyone.now.updateStockStatus(stockList);
	}
	else{
		console.log(this.user.name + " does not have enought balance to buy stock " + stockName);
	}
}

everyone.now.sellStock = function(stockName, units){
	//console.log("User wants to sell stock " + stockName + ", amount: " + units);
	//Update user object
	sellUserStocks(this.user, stockName, parseInt(units));	
	//Update stock prices
	updateStockPrices(stockName, parseInt(units), false);	

	this.now.updateUserStockInfo(this.user);
	everyone.now.updateStockInfo(stockList);
	everyone.now.updateMyStockPrices(stockName);	
}

everyone.now.updateMyStock = function(stockName){
	//console.log("Updating " + this.user.name + " stock price for " + stockName);
	var hasStock = updateMyStockValue(this.user, stockName);
	if(hasStock){
		this.now.updateUserStockInfo(this.user);
	}
}
//Global chat functions
everyone.now.changeRoom = function(newRoom){
	nowjs.getGroup(this.now.room).removeUser(this.user.clientId);
	nowjs.getGroup(newRoom).addUser(this.user.clientId);
	this.now.room = newRoom;
	this.now.receiveMessage("SERVER", "You're now in " + this.now.room);
}

everyone.now.distributeMessage = function(message){
	nowjs.getGroup(this.now.room).now.receiveMessage(this.now.name, message);
};

//Private chat functions
everyone.now.createChatRoom = function(chatRoomName){
	if(chatRoomNameNotInUse(chatRoomName)){
		nowjs.getGroup(this.now.room).removeUser(this.user.clientId);
		nowjs.getGroup(chatRoomName).addUser(this.user.clientId);
		this.now.room = chatRoomName;
		
		var mem = [];
		mem.push({name: this.now.name, id: this.user.clientId});
		var room = {name: this.now.room, members: mem};
		chatRooms.push(room);		
		//get all chat rooms for this user
		var userRooms = getChatRoomsForUser(this.user.clientId, this.now.room);
		this.now.addChatRoom(this.now.room, mem);
		//GUDRUN FOR YOU
		//this.now.addChatRoom(userRooms);
		this.now.receiveMessage("SERVER", "You're now in " + this.now.room);
	}
	else{
		//TODO alert user that chat room name allready exist
		console.log("Cannot create room, name allready exist");
	}
}

everyone.now.addUserToChat = function(clientId, name){
	if(this.now.room != "Main Room" && this.user.name != name){
		everyone.now.getUserResponse(this.now.room, clientId);
	}
} 

everyone.now.userResponseForChat = function(roomName, clientId){
	if(this.user.clientId == clientId){
		nowjs.getGroup(this.now.room).removeUser(this.user.clientId);
		nowjs.getGroup(roomName).addUser(this.user.clientId);
		this.now.room = roomName;
		var currentMembers = getChatMembersofChat(roomName, this.now.name, this.user.clientId);
		//get all chat rooms for this user
		var userRooms = getChatRoomsForUser(this.user.clientId, this.now.room);
		this.now.addChatRoom(this.now.room, currentMembers);
		//GUDRUN FOR YOU
		//this.now.addChatRoom(userRooms);
		this.now.receiveMessage("SERVER", "You're now in " + this.now.room);
		everyone.now.getUserChatUpdateResponse(this.now.room);
	}	
}

everyone.now.userResponseForChatRoomUpdate = function(roomName){
	if(userInChatRoom(this.user.clientId, roomName)){
		room = getChatRoom(roomName);
		var userRooms = getChatRoomsForUser(this.user.clientId, this.now.room);
		//TO GURDUN
		//this.now.updateChatRoomListMembers(userRooms);
		this.now.updateChatRoomListMembers(room);
		//console.log(this.now.name + " belongs to chat room " + roomName);
	}
}


function getRamdonStock(){
	var length = stockList.length;
	var randomIndex = Math.floor(Math.random()*length);
	var raise = Math.floor(Math.random()*2);
	//console.log(randomIndex);
	//var randomStock = stockList[randomIndex];
	var oldPrice = stockList[randomIndex].price;
	var max = (oldPrice / 2) + oldPrice;
	var min = (oldPrice / 2) - oldPrice;
	var subtractOrAdd = Math.floor(Math.random()*(oldPrice / 2));
	var newprice;
	if(raise == 1){
		//console.log("Random raise!");
		newprice = roundNumber((oldPrice + subtractOrAdd),2);
		if(newprice > 1000){
			stockList[randomIndex].price = 1000;
		}
		else{
			stockList[randomIndex].price = newprice;
		}
		stockList[randomIndex].raised = true;
	}
	else{
		//console.log("Random lower!");
		newprice = roundNumber((oldPrice - subtractOrAdd),2);
		if(newprice < 0){
			stockList[randomIndex].price = 1;
		}
		else{
			stockList[randomIndex].price = newprice;
		}		
		stockList[randomIndex].raised = false;
	}
	return stockList[randomIndex];
}

//Random stock price change every 2 minutes
everyone.now.updateStockRandomly = function(){
	//console.log("random stock price update!");
	//update stock prices and user stocks
	var randomStock = getRamdonStock();
	everyone.now.updateStockInfo(stockList);
	everyone.now.updateMyStockPrices(randomStock.name);
};
var recursive2 = function () {
    //console.log("It has been one second! " + "counter: " + time);
	if(OK){
		everyone.now.updateStockRandomly();
	}
	//120000 = 2 minutes
	setTimeout(recursive2,120000);	 
}
recursive2();

//Counter implementation
everyone.now.update = function(){
	everyone.now.countDownTime(format_output());
};

everyone.now.timeIsUp = function(){
	//TODO create a list of winners in descending order for credit
	if(gameOver){
		var results = createWinnerList();
		for(var i = 0; i < results.length; i++){
			console.log((i+1) + " place | user: " + results[i].name + " balance: " + results[i].balance);
		}
		gameOver = false;
	}
	//Let the clients now and update....
	//everyone.now.gameOver(results);
};

var recursive = function () {
    //console.log("It has been one second! " + "counter: " + time);
	if(OK){
		everyone.now.update();
	}
	time = time - 1;
	if(time == -1){
		//TODO stop everything and anounce winner
		gameOver = true;
		console.log("TIME IS UP!!!");
		everyone.now.timeIsUp();
		return;
	}	
	else{
		setTimeout(recursive,1000);	
	}
     
}
recursive();
//Helper functions for counter
function add_leading_zero(n) {
	if(n.toString().length < 2) {
		return '0' + n;
	} else {
		return n;
	}
}

function format_output() {
	var hours, minutes, seconds;
	seconds = time % 60;
	minutes = Math.floor(time / 60) % 60;
	hours = Math.floor(time / 3600);

	seconds = add_leading_zero( seconds );
	minutes = add_leading_zero( minutes );
	hours = add_leading_zero( hours );

	return hours + ':' + minutes + ':' + seconds;
}






